﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
using System.Threading.Tasks;
using System.Xml;

namespace SQLToolsCore
{
    public static class CommonTools
    {
        /// <summary>
        /// 序列化
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static byte[] ObjectToBytes(this object obj)
        {
            if (obj == null)
                return null;

            using MemoryStream ms = new();
            IFormatter formatter = new BinaryFormatter();
            formatter.Serialize(ms, obj);
            return ms.GetBuffer();
        }

        /// <summary>
        /// 反序列化
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static T Deserialize<T>(this byte[] data)
        {
            if (data == null)
                return default;

            using MemoryStream ms = new(data);
            IFormatter formatter = new BinaryFormatter();
            return (T)formatter.Deserialize(ms);
        }

        //获取文件同时反序列化
        public static T LoadContentWithDeserialize<T>(string path)
        {
            string str = LoadContent(path);
            return Deserialize<T>(Convert.FromBase64String(str));
        }

        public static string LoadContent(string path, Encoding encoding = null)
        {
            encoding ??= Encoding.Default;
            var rtnStr = string.Empty;
            using (StreamReader sr = new(path, encoding))
            {
                string line;
                while ((line = sr.ReadLine()) != null)
                {
                    rtnStr += line + "\n";
                }
                sr.Close();
            }
            return rtnStr;
        }

        //保存文件同时序列化
        public static void SaveContentWithSerialize(string path, object o)
        {
            var bytes = ObjectToBytes(o);
            SaveContent(path, Convert.ToBase64String(bytes));
        }

        public static void SaveContent(string path, string content, Encoding encoding = null)
        {
            encoding ??= Encoding.Default;
            FileStream fs = new(path, FileMode.Create, FileAccess.Write);
            using StreamWriter sw = new(fs, encoding);
            sw.Write(content);
            sw.Close();
        }

        //打开文件
        public static void OpenFile(this string filePath)
        {
            using var process = new Process();
            ProcessStartInfo processStartInfo = new(filePath);
            process.StartInfo = processStartInfo;
            //不加会报错
            process.StartInfo.UseShellExecute = true;
            process.Start();
        }

        /// <summary>
        /// 通过指定字符连接字符串
        /// </summary>
        /// <param name="oriStr">原字符串</param>
        /// <param name="concatStr">需要连接的字符串</param>
        /// <param name="splitStr">分隔字符</param>
        /// <returns></returns>
        public static string Concat(this string oriStr, string concatStr, string splitStr = ",")
        {
            return string.IsNullOrWhiteSpace(oriStr) ? concatStr : oriStr + splitStr + concatStr;
        }

        /// <summary>
        /// 浅映射，不匹配的属性将被忽略
        /// </summary>
        /// <typeparam name="TTarget"></typeparam>
        /// <param name="source"></param>
        /// <returns></returns>
        public static TTarget SimpleMapTo<TTarget>(this object source)
        {
            Type sourceType = source.GetType();
            Type targetType = typeof(TTarget);
            TTarget target = (TTarget)Activator.CreateInstance(targetType);

            foreach (var targetProp in targetType.GetProperties())
            {
                try
                {
                    var val = sourceType.GetProperty(targetProp.Name)?.GetValue(source);
                    if (val != null)
                    {
                        targetProp.SetValue(target, val);
                    }
                }
                catch { }
            }

            return target;
        }
    }
}
